`include "defines.v"
module openmips(
	input wire clk,
	input wire rst,
	input wire[31:0] inst_i,
	output wire rom_ce_o,
	output wire[31:0] rom_addr_o
);
	//取指译码锁存器 译码模块连接线
	wire[31:0] if_id_lock_id_pc;
	wire[31:0] if_id_lock_id_inst;
	//******************************
	
	//译码寄存器堆模块连接线
	wire[31:0] id_regfile_reg1_data;
	wire[4:0] id_regfile_reg1_addr;
	wire id_regfile_reg1_read;
	
	wire[31:0] id_regfile_reg2_data;
	wire[4:0] id_regfile_reg2_addr;
	wire id_regfile_reg2_read;
	//******************************
	
	//译码 译码执行锁存器模块连接线
	wire[31:0] id_id_ex_lock_reg1;
	wire[31:0] id_id_ex_lock_reg2;
	wire[4:0] id_id_ex_lock_reg3_addr;
	wire id_id_ex_lock_reg3_write;
	wire[`AluOpWidth:0] id_id_ex_lock_alu_op;
	//******************************
	
	//译码执行锁存器 执行模块连接线
	wire[31:0] id_ex_lock_ex_reg1;
	wire[31:0] id_ex_lock_ex_reg2;
	wire[4:0] id_ex_lock_ex_reg3_addr;
	wire id_ex_lock_ex_reg3_write;
	wire[`AluOpWidth:0] id_ex_lock_ex_alu_op;
	
	//***********************************
	
	//执行 执行访存锁存器模块连接线
	wire[31:0] ex_ex_mem_lock_write_data;
	wire[4:0] ex_ex_mem_lock_write_addr;
	wire ex_ex_mem_lock_write_ce;
		//与hilo寄存器相关信号	
	wire[31:0] ex_ex_mem_lock_hi;
	wire[31:0] ex_ex_mem_lock_lo;
	wire ex_ex_mem_lock_hilo_write_ce;
	//***************************************
	
	
	//执行访存锁存器 访存模块连接线
	wire[31:0] ex_mem_lock_mem_write_data;
	wire[4:0] ex_mem_lock_mem_write_addr;
	wire ex_mem_lock_mem_write_ce;
	
		//与hilo寄存器相关信号	
	wire[31:0] ex_mem_lock_mem_hi;
	wire[31:0] ex_mem_lock_mem_lo;
	wire ex_mem_lock_mem_hilo_write_ce;
	//***************************************
	
	//访存 访存回写锁存器模块连接线
	wire[31:0] mem_mem_wb_lock_write_data;
	wire[4:0] mem_mem_wb_lock_write_addr;
	wire mem_mem_wb_lock_write_ce;
	//***********************************
	
	//访存回写锁存器 寄存器堆模块连接线
	wire[31:0] mem_wb_lock_regfile_write_data;
	wire[4:0] mem_wb_lock_regfile_write_addr;
	wire mem_wb_lock_regfile_write_ce;
	//************************************
	
	//译码 执行模块间 解决数据相关连接线
	wire[4:0] id_ex_write_addr;
	wire id_ex_write_ce;
	wire[31:0] id_ex_write_data;
	//***************************
	
	//译码 访存模块间 解决数据相关连接线
	wire[4:0] id_mem_write_addr;
	wire id_mem_write_ce;
	wire[31:0] id_mem_write_data;
	//***************************
	
	//hilo 执行模块间连接线
	wire[31:0] hilo_ex_hi;
	wire[31:0] hilo_ex_lo;
	//***************************
	
	//访存 访存回写锁存器间   访存 执行模块间连接线
	wire[31:0] mem_mem_wb_lock_and_mem_ex_hi;
	wire[31:0] mem_mem_wb_lock_and_mem_ex_lo;
	wire mem_mem_wb_lock_and_mem_ex_hilo_write_ce;
	//*******************************
	
	//访存回写锁存器 hilo间  访存回写锁存器 执行模块间连接线
	wire[31:0] mem_wb_lock_hilo_and_mem_wb_lock_ex_hi;
	wire[31:0] mem_wb_lock_hilo_and_mem_wb_lock_ex_lo;
	wire mem_wb_lock_hilo_and_mem_wb_lock_ex_hilo_write_ce;
	//**********************************
	//取指模块实例化
	pc_reg pc_reg0(
		.clk(clk),
		.rst(rst),
		.pc(rom_addr_o),
		.ce(rom_ce_o)
	);
	
	//取指译码锁存器模块实例化
	if_id if_id0(
		.clk(clk),
		.rst(rst),
		.if_pc(rom_addr_o),
		.if_inst(inst_i),
		.id_pc(if_id_lock_id_pc),
		.id_inst(if_id_lock_id_inst)
	);
	
	
	//译码模块实例化
	id id0(
		.rst(rst),
		.pc_i(if_id_lock_id_pc),
		.inst_i(if_id_lock_id_inst),
		.reg1_data_i(id_regfile_reg1_data),
		.reg2_data_i(id_regfile_reg2_data),
		.reg1_addr_o(id_regfile_reg1_addr),
		.reg2_addr_o(id_regfile_reg2_addr),
		.reg1_read_o(id_regfile_reg1_read),
		.reg2_read_o(id_regfile_reg2_read),
		//传给id_ex模块的信号
		.reg1_o(id_id_ex_lock_reg1),
		.reg2_o(id_id_ex_lock_reg2),
		.reg3_addr_o(id_id_ex_lock_reg3_addr),
		.reg3_write_o(id_id_ex_lock_reg3_write),
		.alu_op_o(id_id_ex_lock_alu_op),
		// output reg[`AluSelWidth-1:0] alu_sel_o
		
		//执行模块传给译码模块的信号（解决数据相关）
		.ex_write_addr_i(id_ex_write_addr),
		.ex_write_ce_i(id_ex_write_ce),
		.ex_write_data_i(id_ex_write_data),
		//访存模块传给译码模块的信号（解决数据相关）
		.mem_write_addr_i(id_mem_write_addr),
		.mem_write_ce_i(id_mem_write_ce),
		.mem_write_data_i(id_mem_write_data)
	);
	
	//译码执行锁存器模块实例化
	id_ex id_ex0(
		.clk(clk),
		.rst(rst),
		.id_reg1(id_id_ex_lock_reg1),
		.id_reg2(id_id_ex_lock_reg2),
		.id_reg3_addr(id_id_ex_lock_reg3_addr),
		.id_reg3_write(id_id_ex_lock_reg3_write),
		.id_alu_op(id_id_ex_lock_alu_op),
		// input wire[`AluSelWidth-1:0] id_alu_sel,
		.ex_reg1(id_ex_lock_ex_reg1),
		.ex_reg2(id_ex_lock_ex_reg2),
		.ex_reg3_addr(id_ex_lock_ex_reg3_addr),
		.ex_reg3_write(id_ex_lock_ex_reg3_write),
		.ex_alu_op(id_ex_lock_ex_alu_op)
		// output reg[`AluSelWidth-1:0] ex_alu_sel
	);
	
	//执行模块实例化
	ex ex0(
		.rst(rst),
		.reg1_i(id_ex_lock_ex_reg1),
		.reg2_i(id_ex_lock_ex_reg2),
		.reg3_addr_i(id_ex_lock_ex_reg3_addr),
		.reg3_write_i(id_ex_lock_ex_reg3_write),
		.alu_op_i(id_ex_lock_ex_alu_op),
		// input wire[`AluSelWidth-1:0] alu_sel_i,
		.write_data_o(ex_ex_mem_lock_write_data),
		.write_ce_o(ex_ex_mem_lock_write_ce),
		.write_addr_o(ex_ex_mem_lock_write_addr),
		
		//传给id模块的将要写的数据
		.ex_id_write_addr_o(id_ex_write_addr),
		.ex_id_write_ce_o(id_ex_write_ce),
		.ex_id_write_data_o(id_ex_write_data),
		
		//与hilo寄存器相关信号
		.hi_i(hilo_ex_hi),
		.lo_i(hilo_ex_lo),
		.mem_ex_hilo_write_ce_i(mem_mem_wb_lock_and_mem_ex_hilo_write_ce),
		.mem_ex_hi_i(mem_mem_wb_lock_and_mem_ex_hi),
		.mem_ex_lo_i(mem_mem_wb_lock_and_mem_ex_lo),
		.wb_ex_hilo_write_ce_i(mem_wb_lock_hilo_and_mem_wb_lock_ex_hilo_write_ce),
		.wb_ex_hi_i(mem_wb_lock_hilo_and_mem_wb_lock_ex_hi),
		.wb_ex_lo_i(mem_wb_lock_hilo_and_mem_wb_lock_ex_lo),
		.hi_o(ex_ex_mem_lock_hi),
		.lo_o(ex_ex_mem_lock_lo),
		.hilo_write_ce_o(ex_ex_mem_lock_hilo_write_ce)
	);
	
	//执行访存锁存器模块实例化
	ex_mem ex_mem0(
		.clk(clk),
		.rst(rst),
		.write_data_i(ex_ex_mem_lock_write_data),
		.write_ce_i(ex_ex_mem_lock_write_ce),
		.write_addr_i(ex_ex_mem_lock_write_addr),
		.write_data_o(ex_mem_lock_mem_write_data),
		.write_ce_o(ex_mem_lock_mem_write_ce),
		.write_addr_o(ex_mem_lock_mem_write_addr),
		//与hilo寄存器相关的数据
		.hi_i(ex_ex_mem_lock_hi),
		.lo_i(ex_ex_mem_lock_lo),
		.hilo_write_ce_i(ex_ex_mem_lock_hilo_write_ce),
		.hi_o(ex_mem_lock_mem_hi),
		.lo_o(ex_mem_lock_mem_lo),
		.hilo_write_ce_o(ex_mem_lock_mem_hilo_write_ce)
	);
	
	//访存模块实例化
	mem mem0(
		.rst(rst),
		.write_data_i(ex_mem_lock_mem_write_data),
		.write_ce_i(ex_mem_lock_mem_write_ce),
		.write_addr_i(ex_mem_lock_mem_write_addr),
		.write_data_o(mem_mem_wb_lock_write_data),
		.write_ce_o(mem_mem_wb_lock_write_ce),
		.write_addr_o(mem_mem_wb_lock_write_addr),
		
		//传给id模块的将要写的数据
		.mem_id_write_addr_o(id_mem_write_addr),
		.mem_id_write_ce_o(id_mem_write_ce),
		.mem_id_write_data_o(id_mem_write_data),
		
		//与hilo寄存器相关的数据
		.hi_i(ex_mem_lock_mem_hi),
		.lo_i(ex_mem_lock_mem_lo),
		.hilo_write_ce_i(ex_mem_lock_mem_hilo_write_ce),
		.hi_o(mem_mem_wb_lock_and_mem_ex_hi),
		.lo_o(mem_mem_wb_lock_and_mem_ex_lo),
		.hilo_write_ce_o(mem_mem_wb_lock_and_mem_ex_hilo_write_ce)
	
	);
	mem_wb mem_wb0(
		.clk(clk),
		.rst(rst),
		.write_data_i(mem_mem_wb_lock_write_data),
		.write_ce_i(mem_mem_wb_lock_write_ce),
		.write_addr_i(mem_mem_wb_lock_write_addr),
		.write_data_o(mem_wb_lock_regfile_write_data),
		.write_ce_o(mem_wb_lock_regfile_write_ce),
		.write_addr_o(mem_wb_lock_regfile_write_addr),
		//与hilo寄存器相关的数据
		.hi_i(mem_mem_wb_lock_and_mem_ex_hi),
		.lo_i(mem_mem_wb_lock_and_mem_ex_lo),
		.hilo_write_ce_i(mem_mem_wb_lock_and_mem_ex_hilo_write_ce),
		.hi_o(mem_wb_lock_hilo_and_mem_wb_lock_ex_hi),
		.lo_o(mem_wb_lock_hilo_and_mem_wb_lock_ex_lo),
		.hilo_write_ce_o(mem_wb_lock_hilo_and_mem_wb_lock_ex_hilo_write_ce)
);
	regfile regfile0(
		.clk(clk),
		.rst(rst),
		//写端口
		.waddr(mem_wb_lock_regfile_write_addr),
		.wdata(mem_wb_lock_regfile_write_data),
		.we(mem_wb_lock_regfile_write_ce),
		//读端口1
		.raddr1(id_regfile_reg1_addr),
		.re1(id_regfile_reg1_read),
		.rdata1(id_regfile_reg1_data),
		//读端口2
		.raddr2(id_regfile_reg2_addr),
		.re2(id_regfile_reg2_read),
		.rdata2(id_regfile_reg2_data)
	);

	hilo_reg hilo_reg0(
		.clk(clk),
		.rst(rst),
		.write_ce(mem_wb_lock_hilo_and_mem_wb_lock_ex_hilo_write_ce),
		.hi_i(mem_wb_lock_hilo_and_mem_wb_lock_ex_hi),
		.lo_i(mem_wb_lock_hilo_and_mem_wb_lock_ex_lo),
		.hi_o(hilo_ex_hi),
		.lo_o(hilo_ex_lo)
);
endmodule